Micron Document
🎖️GitЯра🎖️


Displaying Raw • Download

core/network/src/commonTest/kotlin/org/meshtastic/core/network/transport/HeartbeatSenderTest.kt bd2863243bab6eb213401d949839a2bc74dde7e2 (bd286324) Text, 6.36 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.network.transport

Tff7b72import T7ee787kotlinx.coroutines.Job
Tff7b72import T7ee787kotlinx.coroutines.delay
Tff7b72import T7ee787kotlinx.coroutines.isActive
Tff7b72import T7ee787kotlinx.coroutines.launch
Tff7b72import T7ee787kotlinx.coroutines.test.TestScope
Tff7b72import T7ee787kotlinx.coroutines.test.advanceTimeBy
Tff7b72import T7ee787kotlinx.coroutines.test.runCurrent
Tff7b72import T7ee787kotlinx.coroutines.test.runTest
Tff7b72import T7ee787org.meshtastic.proto.ToRadio
Tff7b72import T7ee787kotlin.test.Test
Tff7b72import T7ee787kotlin.test.assertEquals
Tff7b72import T7ee787kotlin.test.assertFalse
Tff7b72import T7ee787kotlin.test.assertNotNull
Tff7b72import T7ee787kotlin.test.assertNull
Tff7b72import T7ee787kotlin.test.assertTrue
Tff7b72import T7ee787kotlin.time.Duration
Tff7b72import T7ee787kotlin.time.Duration.Companion.seconds

Tff7b72class T56d364HeartbeatSenderTest Tb4b4b4{

Tf0883e@Test
Tff7b72fun Td2a8ff`sendHeartbeat encodes a heartbeat and runs afterHeartbeat after sending`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sentPackets Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3ByteArrayTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3afterHeartbeatCalls Tff7b72= T79c0ff0
Tff7b72val Te6edf3sender Tff7b72=
Te6edf3HeartbeatSenderTb4b4b4(
Te6edf3sendToRadio Tff7b72= Tb4b4b4{ Te6edf3sentPacketsTb4b4b4.Te6edf3addTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3afterHeartbeat Tff7b72= Tb4b4b4{
Te6edf3afterHeartbeatCallsTff7b72+Tff7b72+
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3sentPacketsTb4b4b4.Te6edf3sizeTb4b4b4)
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Te6edf3assertTrueTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3sendHeartbeatTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3sentPacketsTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3afterHeartbeatCallsTb4b4b4)

Tff7b72val Te6edf3message Tff7b72= Te6edf3ToRadioTb4b4b4.Te6edf3ADAPTERTb4b4b4.Te6edf3decodeTb4b4b4(Te6edf3sentPacketsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3heartbeat Tff7b72= Te6edf3assertNotNullTb4b4b4(Te6edf3messageTb4b4b4.Te6edf3heartbeatTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3heartbeatTb4b4b4.Te6edf3nonceTb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3messageTb4b4b4.Te6edf3packetTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`rejected heartbeat skips post-send work`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sentPackets Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3ByteArrayTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3afterHeartbeatCalls Tff7b72= T79c0ff0
Tff7b72var Te6edf3accept Tff7b72= Tff7b72false
Tff7b72val Te6edf3sender Tff7b72=
Te6edf3HeartbeatSenderTb4b4b4(
Te6edf3sendToRadio Tff7b72= Tb4b4b4{ Tff7b72if Tb4b4b4(Te6edf3acceptTb4b4b4) Te6edf3sentPacketsTb4b4b4.Te6edf3addTb4b4b4(Tffa657itTb4b4b4) Tff7b72else Tff7b72false Tb4b4b4}Tb4b4b4,
Te6edf3afterHeartbeat Tff7b72= Tb4b4b4{ Te6edf3afterHeartbeatCallsTff7b72+Tff7b72+ Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Te6edf3assertFalseTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3sendHeartbeatTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3afterHeartbeatCallsTb4b4b4)

Te6edf3accept Tff7b72= Tff7b72true
Te6edf3assertTrueTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3sendHeartbeatTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3afterHeartbeatCallsTb4b4b4)
Te6edf3assertHeartbeatsTb4b4b4(Te6edf3sentPacketsTb4b4b4, T79c0ff0Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`heartbeat loop emits at the configured interval`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sentPackets Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3ByteArrayTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3sender Tff7b72= Te6edf3HeartbeatSenderTb4b4b4(Te6edf3sendToRadio Tff7b72= Tb4b4b4{ Te6edf3sentPacketsTb4b4b4.Te6edf3addTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}Tb4b4b4)
Tff7b72val Te6edf3interval Tff7b72= T79c0ff5.Te6edf3seconds
Tff7b72val Te6edf3job Tff7b72= Te6edf3launchFiniteHeartbeatLoopTb4b4b4(Te6edf3sender Tff7b72= Te6edf3senderTb4b4b4, Te6edf3interval Tff7b72= Te6edf3intervalTb4b4b4, Te6edf3repeatCount Tff7b72= T79c0ff3Tb4b4b4)

Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3assertHeartbeatsTb4b4b4(Te6edf3sentPacketsTb4b4b4, T79c0ff0Tb4b4b4)

Te6edf3advanceTimeByTb4b4b4(Te6edf3intervalTb4b4b4.Te6edf3inWholeMillisecondsTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3assertHeartbeatsTb4b4b4(Te6edf3sentPacketsTb4b4b4, T79c0ff0Tb4b4b4, T79c0ff1Tb4b4b4)

Te6edf3advanceTimeByTb4b4b4(Te6edf3intervalTb4b4b4.Te6edf3inWholeMillisecondsTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3assertHeartbeatsTb4b4b4(Te6edf3sentPacketsTb4b4b4, T79c0ff0Tb4b4b4, T79c0ff1Tb4b4b4, T79c0ff2Tb4b4b4)

Te6edf3jobTb4b4b4.Te6edf3cancelTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`cancelling a heartbeat loop stops additional heartbeats`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sentPackets Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3ByteArrayTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3sender Tff7b72= Te6edf3HeartbeatSenderTb4b4b4(Te6edf3sendToRadio Tff7b72= Tb4b4b4{ Te6edf3sentPacketsTb4b4b4.Te6edf3addTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}Tb4b4b4)
Tff7b72val Te6edf3interval Tff7b72= T79c0ff5.Te6edf3seconds
Tff7b72val Te6edf3job Tff7b72= Te6edf3launchRepeatingHeartbeatLoopTb4b4b4(Te6edf3sender Tff7b72= Te6edf3senderTb4b4b4, Te6edf3interval Tff7b72= Te6edf3intervalTb4b4b4)

Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3advanceTimeByTb4b4b4(Te6edf3intervalTb4b4b4.Te6edf3inWholeMillisecondsTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3assertHeartbeatsTb4b4b4(Te6edf3sentPacketsTb4b4b4, T79c0ff0Tb4b4b4, T79c0ff1Tb4b4b4)

Te6edf3jobTb4b4b4.Te6edf3cancelTb4b4b4(Tb4b4b4)
Te6edf3advanceTimeByTb4b4b4(Te6edf3intervalTb4b4b4.Te6edf3inWholeMilliseconds Tff7b72* T79c0ff5Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3assertHeartbeatsTb4b4b4(Te6edf3sentPacketsTb4b4b4, T79c0ff0Tb4b4b4, T79c0ff1Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`zero interval sends all scheduled heartbeats without advancing time`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sentPackets Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3ByteArrayTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3sender Tff7b72= Te6edf3HeartbeatSenderTb4b4b4(Te6edf3sendToRadio Tff7b72= Tb4b4b4{ Te6edf3sentPacketsTb4b4b4.Te6edf3addTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}Tb4b4b4)

Te6edf3backgroundScopeTb4b4b4.Te6edf3launch Tb4b4b4{ Te6edf3repeatTb4b4b4(T79c0ff3Tb4b4b4) Tb4b4b4{ Te6edf3senderTb4b4b4.Te6edf3sendHeartbeatTb4b4b4(Tb4b4b4) Tb4b4b4} Tb4b4b4}
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(T79c0ff0LTb4b4b4, Te6edf3testSchedulerTb4b4b4.Te6edf3currentTimeTb4b4b4)
Te6edf3assertHeartbeatsTb4b4b4(Te6edf3sentPacketsTb4b4b4, T79c0ff0Tb4b4b4, T79c0ff1Tb4b4b4, T79c0ff2Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`restarting a heartbeat loop resumes with the next nonce`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sentPackets Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3ByteArrayTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3sender Tff7b72= Te6edf3HeartbeatSenderTb4b4b4(Te6edf3sendToRadio Tff7b72= Tb4b4b4{ Te6edf3sentPacketsTb4b4b4.Te6edf3addTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}Tb4b4b4)
Tff7b72val Te6edf3interval Tff7b72= T79c0ff5.Te6edf3seconds

Tff7b72val Te6edf3firstJob Tff7b72= Te6edf3launchRepeatingHeartbeatLoopTb4b4b4(Te6edf3sender Tff7b72= Te6edf3senderTb4b4b4, Te6edf3interval Tff7b72= Te6edf3intervalTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3advanceTimeByTb4b4b4(Te6edf3intervalTb4b4b4.Te6edf3inWholeMillisecondsTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3firstJobTb4b4b4.Te6edf3cancelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3secondJob Tff7b72= Te6edf3launchFiniteHeartbeatLoopTb4b4b4(Te6edf3sender Tff7b72= Te6edf3senderTb4b4b4, Te6edf3interval Tff7b72= Te6edf3intervalTb4b4b4, Te6edf3repeatCount Tff7b72= T79c0ff2Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3advanceTimeByTb4b4b4(Te6edf3intervalTb4b4b4.Te6edf3inWholeMillisecondsTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3secondJobTb4b4b4.Te6edf3cancelTb4b4b4(Tb4b4b4)

Te6edf3assertHeartbeatsTb4b4b4(Te6edf3sentPacketsTb4b4b4, T79c0ff0Tb4b4b4, T79c0ff1Tb4b4b4, T79c0ff2Tb4b4b4, T79c0ff3Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Te6edf3TestScopeTb4b4b4.Td2a8fflaunchRepeatingHeartbeatLoopTb4b4b4(Te6edf3senderTb4b4b4: Te6edf3HeartbeatSenderTb4b4b4, Te6edf3intervalTb4b4b4: Te6edf3DurationTb4b4b4)Tb4b4b4: Te6edf3Job Tff7b72=
Te6edf3backgroundScopeTb4b4b4.Te6edf3launch Tb4b4b4{
Tff7b72while Tb4b4b4(Te6edf3isActiveTb4b4b4) Tb4b4b4{
Te6edf3senderTb4b4b4.Te6edf3sendHeartbeatTb4b4b4(Tb4b4b4)
Te6edf3delayTb4b4b4(Te6edf3intervalTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Te6edf3TestScopeTb4b4b4.Td2a8fflaunchFiniteHeartbeatLoopTb4b4b4(
Te6edf3senderTb4b4b4: Te6edf3HeartbeatSenderTb4b4b4,
Te6edf3intervalTb4b4b4: Te6edf3DurationTb4b4b4,
Te6edf3repeatCountTb4b4b4: Tffa657IntTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3Job Tff7b72= Te6edf3backgroundScopeTb4b4b4.Te6edf3launch Tb4b4b4{
Te6edf3repeatTb4b4b4(Te6edf3repeatCountTb4b4b4) Tb4b4b4{
Te6edf3senderTb4b4b4.Te6edf3sendHeartbeatTb4b4b4(Tb4b4b4)
Te6edf3delayTb4b4b4(Te6edf3intervalTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffassertHeartbeatsTb4b4b4(Te6edf3sentPacketsTb4b4b4: Te6edf3ListTff7b72<Te6edf3ByteArrayTff7b72>Tb4b4b4, Tff7b72vararg Te6edf3expectedNoncesTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3assertEqualsTb4b4b4(Te6edf3expectedNoncesTb4b4b4.Te6edf3sizeTb4b4b4, Te6edf3sentPacketsTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3sentPacketsTb4b4b4.Te6edf3zipTb4b4b4(Te6edf3expectedNoncesTb4b4b4.Te6edf3toListTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3forEachIndexed Tb4b4b4{ Te6edf3indexTb4b4b4, Tb4b4b4(Te6edf3packetTb4b4b4, Te6edf3expectedNonceTb4b4b4) Tff7b72-Tff7b72>
Tff7b72val Te6edf3message Tff7b72= Te6edf3ToRadioTb4b4b4.Te6edf3ADAPTERTb4b4b4.Te6edf3decodeTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72val Te6edf3heartbeat Tff7b72= Te6edf3assertNotNullTb4b4b4(Te6edf3messageTb4b4b4.Te6edf3heartbeatTb4b4b4, Ta5d6ff"Ta5d6ffMissing heartbeat at index Tffd700$Te6edf3indexTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3expectedNonceTb4b4b4, Te6edf3heartbeatTb4b4b4.Te6edf3nonceTb4b4b4, Ta5d6ff"Ta5d6ffUnexpected nonce at index Tffd700$Te6edf3indexTa5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.08s